from pydantic import BaseModel
from typing import Optional, List
from fastapi.param_functions import Form
from typing_extensions import Annotated, Doc
import datetime

# 登录的请求
class OAuth2RequestForm:
    """
    This is a dependency class to collect the `username` and `password` as form data
    for an OAuth2 password flow.

    The OAuth2 specification dictates that for a password flow the data should be
    collected using form data (instead of JSON) and that it should have the specific
    fields `username` and `password`.

    All the initialization parameters are extracted from the request.

    Read more about it in the
    [FastAPI docs for Simple OAuth2 with Password and Bearer](https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/).

    ## Example

    ```python
    from typing import Annotated

    from fastapi import Depends, FastAPI
    from fastapi.security import OAuth2PasswordRequestForm

    app = FastAPI()


    @app.post("/login")
    def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):
        data = {}
        data["scopes"] = []
        for scope in form_data.scopes:
            data["scopes"].append(scope)
        if form_data.client_id:
            data["client_id"] = form_data.client_id
        if form_data.client_secret:
            data["client_secret"] = form_data.client_secret
        return data
    ```

    Note that for OAuth2 the scope `items:read` is a single scope in an opaque string.
    You could have custom internal logic to separate it by colon caracters (`:`) or
    similar, and get the two parts `items` and `read`. Many applications do that to
    group and organize permissions, you could do it as well in your application, just
    know that that it is application specific, it's not part of the specification.
    """

    def __init__(self,
        *,
        username: Annotated[
            str,
            Form(),
            Doc(
                """
                `username` string. The OAuth2 spec requires the exact field name
                `username`.
                """
            ),
        ],
        password: Annotated[
            str,
            Form(),
            Doc(
                """
                `password` string. The OAuth2 spec requires the exact field name
                `password".
                """
            ),
        ]
    ):
        self.username = username
        self.password = password


class Token(BaseModel):
    access_token: str
    token_type: str = "bearer"





class SignUp(BaseModel):
    name: str
    password: str
    email: Optional[str] = None
    phone: Optional[str] = None
    verification_code: Optional[str] = None
    class Config:
        json_schema_extra = {
            "example": {
                "name": "张三",
                "password": "密码: 英文字母 或 数字 或 符号(, . _ -)",
                "phone": "手机号 13800138000",
                "email": "user@example.com",
                "verification_code": "6689ABC"
            }
        }


# ==================== 权限系统相关模式 ====================

# 角色相关模式
class RoleBase(BaseModel):
    """角色基础模式"""
    name: str
    code: str
    description: Optional[str] = None
    is_active: bool = True


class RoleCreate(RoleBase):
    """创建角色模式"""
    pass


class RoleUpdate(BaseModel):
    """更新角色模式"""
    name: Optional[str] = None
    code: Optional[str] = None
    description: Optional[str] = None
    is_active: Optional[bool] = None


class RoleResponse(RoleBase):
    """角色响应模式"""
    id: int
    create_time: datetime.datetime
    update_time: datetime.datetime
    
    class Config:
        from_attributes = True


# 权限相关模式
class PermissionBase(BaseModel):
    """权限基础模式"""
    name: str
    code: str
    resource: str
    action: str
    description: Optional[str] = None
    is_active: bool = True


class PermissionCreate(PermissionBase):
    """创建权限模式"""
    pass


class PermissionUpdate(BaseModel):
    """更新权限模式"""
    name: Optional[str] = None
    code: Optional[str] = None
    resource: Optional[str] = None
    action: Optional[str] = None
    description: Optional[str] = None
    is_active: Optional[bool] = None


class PermissionResponse(PermissionBase):
    """权限响应模式"""
    id: int
    create_time: datetime.datetime
    update_time: datetime.datetime
    
    class Config:
        from_attributes = True


# 用户角色关联模式
class UserRoleBase(BaseModel):
    """用户角色关联基础模式"""
    user_id: int
    role_id: int


class UserRoleCreate(UserRoleBase):
    """创建用户角色关联模式"""
    pass


class UserRoleResponse(UserRoleBase):
    """用户角色关联响应模式"""
    id: int
    create_time: datetime.datetime
    
    class Config:
        from_attributes = True


# 角色权限关联模式
class RolePermissionBase(BaseModel):
    """角色权限关联基础模式"""
    role_id: int
    permission_id: int


class RolePermissionCreate(RolePermissionBase):
    """创建角色权限关联模式"""
    pass


class RolePermissionResponse(RolePermissionBase):
    """角色权限关联响应模式"""
    id: int
    create_time: datetime.datetime
    
    class Config:
        from_attributes = True


# 用户权限查询模式
class UserPermissionsResponse(BaseModel):
    """用户权限查询响应模式"""
    user_id: int
    roles: List[RoleResponse]
    permissions: List[PermissionResponse]
    
    class Config:
        from_attributes = True


# 角色权限查询模式
class RolePermissionsResponse(BaseModel):
    """角色权限查询响应模式"""
    role_id: int
    role: RoleResponse
    permissions: List[PermissionResponse]
    
    class Config:
        from_attributes = True
